package com.lwei.tallybook.base.dto;

import com.lwei.tallybook.base.domain.Account;
import com.lwei.tallybook.base.domain.AccountBook;
import com.lwei.tallybook.base.domain.rel.RelBillAccount;
import com.lwei.tallybook.base.domain.rel.RelBookAccount;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 账单展示实体
 * @author sks.lwei
 */
@ToString
@NoArgsConstructor
public class AccountBillDTO {

    /**
     * 账单uuid
     */
    @Getter
    @Setter
    private String billUuid;
    /**
     * 展示截止日期
     */
    @Getter
    @Setter
    private Date date;
    /**
     * 创建时间
     */
    @Getter
    @Setter
    private Date creatDate;
    /**
     * 总费用
     */
    @Getter
    @Setter
    private double total;

    /**
     * 账单明细
     */
    @Getter
    private List<Bill> bills;

    /**
     * 关联的账本
     */
    @Getter
    @Setter
    private List<AccountBook> bookList;
    /**
     * 是否结算
     */
    @Getter
    @Setter
    private Boolean close;

    /**
     * 对象缓存
     * 每个人的账单明细
     */
    private Map<String, Bill> billMap;

    /* ----构造------ */

    public AccountBillDTO(Double total, List<RelBillAccount> relBillAccounts, Map<String, Account> accountMap){
        this.total = total;
        if(relBillAccounts.size() > 0){
            this.bills = relBillAccounts.stream().map(relBillAccount ->
                    new Bill(accountMap.get(relBillAccount.getAccountUuid()), relBillAccount.getPrice())).collect(Collectors.toList());
        }
    }

    /* ---方法--- */

    /**
     * 累加
     */
    public synchronized void calculateAdd(Account account, double price){
        if(billMap == null){
            this.billMap = new HashMap<>();
        }

        Bill bill = billMap.get(account.getUuid());
        if(bill == null){
            //初始化一个bill
            bill = new Bill(account, 0);
        }
        bill.setMoney(bill.getMoney() + price);

        billMap.put(bill.getAccountUuid(), bill);
    }

    /**
     * 生成账单
     * 在对象生成之后调用一次
     * 原理：将billMap的临时数据转换到bills
     */
    public synchronized void creatBills(){
        if(this.billMap != null && billMap.size() > 0){

            List<Bill> res = new ArrayList<>(billMap.size());
            Set<Map.Entry<String, Bill>> entries = billMap.entrySet();
            for (Map.Entry<String, Bill> entry : entries) {
                Bill bill = entry.getValue();
                res.add(bill);
            }
            this.bills =  res;
        }else {
            this.bills = new ArrayList<>(0);
        }
    }

    /**
     * 个人金额明细
     */
    @Getter
    @Setter
    @NoArgsConstructor
    public static class Bill {

        /**
         * 人
         */
        private String accountUuid;
        private String accountName;

        /**
         * 金额
         */
        private double money;

        public Bill(Account account, double money){
            this.accountName = account.getUserName();
            this.accountUuid = account.getUuid();
            this.money = money;
        }

        //获取绝对值
        public double getAbsMoney(){
            return Math.abs(this.money);
        }

    }

}
